//
//  NetWork.m
//  HeWeiZhiNeng
//
//  Created by chengzhang Yan on 2017/12/1.
//  Copyright © 2017年 YanCeyMichael.github.io. All rights reserved.
//

#import "NetWork.h"
#import "NetLogger.h"

static NetWork *_instance = nil;
static dispatch_once_t onceToken;

@implementation NetWork

/**
 初始化
 
 @return 初始化方法
 */
- (instancetype)init
{
    self = [super init];
    if (self)
    {
        _manager = [AFHTTPSessionManager manager];
        _manager.requestSerializer = [AFHTTPRequestSerializer serializer];
        _manager.responseSerializer = [AFHTTPResponseSerializer serializer];
        _manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
        _manager.requestSerializer.timeoutInterval = 30.f;
//        [_manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
//        _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain",@"application/json",@"text/json",@"text/javascript",@"text/html", @"charset=utf-8", nil];;
        //[NSSet setWithObjects:@"text/plain",@"application/json",@"text/json",@"text/javascript",@"text/html", @"charset=utf-8", nil];
        // https
        AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
        //单向验证  请求处加上一下代码 就OK
        [policy setValidatesDomainName:NO];
        policy.allowInvalidCertificates = YES; //允许无效的证书
        _manager.securityPolicy = policy;
        [_manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
        _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"application/json",@"text/json",@"text/javascript",@"text/plain", nil];
    }
    return self;
}

/**
 单例方法
 
 @return 单例方法
 */
+ (NetWork *)sharedManager
{
    dispatch_once(&onceToken, ^{
        if (!_instance)
        {
            _instance = [[NetWork alloc] init];
        }
    });
    return _instance;
}

#pragma mark - core function , private method
/**
 核心网络URL请求函数
 
 @param serviceResources 资源层(非接口字段)
 @param networkMethodType 请求类型:GET/POST/PUT/DELETE
 @param params 所需传递参数
 @note for methodType: you can set an dictionary
 @param callback 返回结果的回调
 */

- (void)executeURLRequest:(NSString *)serviceResources methodType:(NetWorkMethodType)networkMethodType params:(id)params callback:(void(^)(DataResponse *response))callback
{
    //设置Url
    NSString *url = [[kServiceHost stringByAppendingString:kApi] stringByAppendingString:serviceResources];
    url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //中文转义
    debug_NSLog(@"=---%@",url);
    //设置参数
    NSMutableDictionary *paramsDictionary = [[NSMutableDictionary alloc] initWithDictionary:params];
    
    //是否携带token
    //在这里设置 token 也就是 设置 kAppId 设置 kKey 设置时间戳,以及MD5 加密
    //我没设置好,你自己设置一下吧,然后找一个MD5加密的工具,可以去github上拿一个.
    NSDate *dateObc = [NSDate date];
    NSString *Timestamp = [NSString stringWithFormat:@"%d",(int)[dateObc timeIntervalSince1970]];
//    [NSString stringWithFormat:@"%d",(int)[dateObc timeIntervalSince1970]];
    // @"1512454752";
    NSData *dictData = [NSJSONSerialization dataWithJSONObject:paramsDictionary options:NSJSONWritingPrettyPrinted error:nil];
    NSString *jsonString = [[NSString alloc]initWithData:dictData encoding:NSUTF8StringEncoding];
    NSString *Signature = [NSString stringWithFormat:@"%@%@%@%@",kAppId,Timestamp,kKey,jsonString];
    debug_NSLog(@"-=-=-=-=-=-=-=-=-=%@,%@,%@",Timestamp,[[SingleManager shareManager] md5:Signature],Signature);
    [self.manager.requestSerializer setValue:kAppId forHTTPHeaderField:@"appId"];
    [self.manager.requestSerializer setValue:[[SingleManager shareManager] md5:Signature] forHTTPHeaderField:@"signature"];
    [self.manager.requestSerializer setValue:Timestamp forHTTPHeaderField:@"timestamp"];
    
    [NetLogger logInfoWithRequstApiName:url requestParams:paramsDictionary];
    switch (networkMethodType) {
        case NetWorkMethodGET:
        {
            [self.manager GET:url parameters:paramsDictionary progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
                DataResponse *response = [DataResponse mj_objectWithKeyValues:jsonDic];
                [self handleTheSuccessfullNetWorkResultWithTheResponse:response callback:^(DataResponse *response) {
                    callback(response);
                }];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                debug_NSLog(@"error:%@,error.description:%@", error, error.description);
                [self handleTheFailurefullNetWorkResult];
            }];
            
        }
            break;
        case NetWorkMethodPUT:
        {
            [self.manager PUT:url parameters:paramsDictionary success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
                DataResponse *response = [DataResponse mj_objectWithKeyValues:jsonDic];
                [self handleTheSuccessfullNetWorkResultWithTheResponse:response callback:^(DataResponse *response) {
                    callback(response);
                }];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                debug_NSLog(@"error:%@,error.description:%@", error, error.description);
                [self handleTheFailurefullNetWorkResult];
            }];
            
        }
            break;
        case NetWorkMethodPOST:
        {
            [self.manager POST:url parameters:paramsDictionary progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
                debug_NSLog(@"%@",jsonDic);
                DataResponse *response = [DataResponse mj_objectWithKeyValues:jsonDic];
                [self handleTheSuccessfullNetWorkResultWithTheResponse:response callback:^(DataResponse *response) {
                    callback(response);
                }];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                debug_NSLog(@"error:%@,error.description:%@", error, error.description);
                [self handleTheFailurefullNetWorkResult];
            }];
        }
            break;
        case NetWorkMethodDELETE:
        {
            [self.manager DELETE:url parameters:paramsDictionary success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
                DataResponse *response = [DataResponse mj_objectWithKeyValues:jsonDic];
                [self handleTheSuccessfullNetWorkResultWithTheResponse:response callback:^(DataResponse *response) {
                    callback(response);
                }];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                debug_NSLog(@"error:%@,error.description:%@", error, error.description);
                [self handleTheFailurefullNetWorkResult];
            }];
        }
            break;
        default:
            break;
    }
    
    
    
}


#pragma mark ---- handle the data flow
/**
 处理网络请求成功之后的方法
 
 @param response 获取到的json字典
 @param callback 回调结果
 */
- (void)handleTheSuccessfullNetWorkResultWithTheResponse:(DataResponse *)response callback:(void(^)(DataResponse *response))callback
{
    if ([response.code isEqualToString:@""]) {  //请求数据正常
        //直接过
    }
    else {
        //请求数据不正常 以及  是否要弹窗提醒
        //弹窗
        //  [response.tip tipAction];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:response.message delegate:self cancelButtonTitle:nil otherButtonTitles:@"好的", nil];
        [alert show];
    }
    
    if (callback != nil)
    {
        callback(response);
    }
    
}

/**
 处理网络请求失败之后的方法
 */
- (void)handleTheFailurefullNetWorkResult
{
    //弹窗
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"网络异常" delegate:self cancelButtonTitle:nil otherButtonTitles:@"好的", nil];
    [alert show];
}

#pragma mark -----

/**
 注册入口

 @param userName userName description
 @param userpwd userpwd description
 @param callback callback description
 */
- (void)registerWithUserName:(NSString *)userName userpwd:(NSString *)userpwd CallBack:(void(^)(DataResponse *response))callback
{
    NSMutableDictionary *params = [@{@"userName":userName,
                                     @"userpwd":userpwd,
                                     @"channel":kChannel,
                                     @"version":kVersion} mutableCopy];
    
    [self executeURLRequest:kRegistUrl methodType:(NetWorkMethodPOST) params:params callback:^(DataResponse *response) {
        callback(response);
    }];
}

/**
 发送手机验证码
 
 @param phone phone description
 */
- (void)sendMessageWithPhone:(NSString *)phone CallBack:(void(^)(DataResponse *response))callback
{
    NSDictionary *params = @{@"phone":phone};
    [self executeURLRequest:kSendMSUrl methodType:(NetWorkMethodPOST) params:params callback:^(DataResponse *response) {
        callback(response);
    }];
}

#pragma mark ----- car perform action

/**
 操作终端

 @param carId carId description
 @param carPerform carPerform description
 @param callback callback description
 */
- (void)actionForOperationTheCarByCarId:(NSString *)carId action:(CarPerformActionType)carPerform CallBack:(void(^)(DataResponse *response))callback
{
    NSDictionary *params = @{@"carId":carId,
                             @"action":@(carPerform)};
    [self executeURLRequest:kCarOperationUrl methodType:(NetWorkMethodGET) params:params callback:^(DataResponse *response) {
        callback(response);
    }];
}







@end
